Skip to content

feat: Vis.to_gltf() / .to_threejs() / .export_mtlx() method sugar#79

Merged
gerchowl merged 3 commits intomainfrom
feature/78-vis-adapter-methods
Apr 19, 2026
Merged

feat: Vis.to_gltf() / .to_threejs() / .export_mtlx() method sugar#79
gerchowl merged 3 commits intomainfrom
feature/78-vis-adapter-methods

Conversation

@gerchowl
Copy link
Copy Markdown
Contributor

@gerchowl gerchowl commented Apr 19, 2026

Summary

Adds method-form discoverability on Vis for the output adapters. m.vis.<TAB> now surfaces to_gltf(), to_threejs(), export_mtlx(). Zero architectural change — methods are thin delegates to the existing module-level functions, which remain the source of truth.

Drop-in for end users: pymat.vis.to_gltf(material) continues to work exactly as before. No deprecation, no breaking change, no caller churn.

Closes #78. Complements mat-vis#93 (the architecturally-cleaner VisAsset proposal — once that lands, these methods become one-line forwards to self._asset.to_gltf()).

What changed

  • pymat.vis.adaptersto_gltf, to_threejs, export_mtlx accept either a Material or a Vis (duck-typed via .vis). Backward-compatible for all existing call sites.
  • pymat.vis._model.Vis — new to_threejs(), to_gltf(*, name=None), export_mtlx(out, *, name=None) methods delegating to the module-level functions. No logic duplication.
  • Back-reference: none. The polymorphic adapter path avoids needing Vis → Material coupling.

Tests

  • tests/test_adapters.py::TestAdapterPolymorphismto_*(m) == to_*(m.vis).
  • tests/test_adapters.py::TestVisAdapterMethodsm.vis.to_*() == to_*(m).
  • tests/test_adapters.py::TestAdapterOnDetachedVis — full adapter path on a Vis() constructed with no owning Material.
  • Duck-typing invariant, keyword-only name= signature, and method-surface discoverability each pinned by a dedicated test.
  • Two claim-backfills from the build123d#1270 comment draft folded in:
    • test_e2e_vis.py::test_mtlx_xml_returns_materialx_string.
    • test_integration.py::TestGltfMaterialPassthrough — pins the real build123d glTF behavior (apply_to preserves base color only; direct shape.material doesn't reach the exporter), documenting the gap that build123d#1270 closes.

Test plan

  • Full suite green locally — 299 passed, 18 skipped.
  • 15 new tests covering the polymorphic-adapter + Vis-method sugar surface.

Out of scope

  • Architectural consolidation (VisAsset in mat-vis-client): separate issue mat-vis#93, needs design conversation with the build123d consumer.
  • glTF metalness+roughness texture packing: separate issue mat-vis#91.

Add method-form discoverability on Vis without touching the
architectural separation that keeps adapters as pure module-level
transformations.

Drop-in: method and module-level produce identical output; the
existing pymat.vis.to_gltf(material) call site stays untouched.

- Adapters become polymorphic: to_gltf / to_threejs / export_mtlx
  accept either a Material or a standalone Vis (duck-typed via the
  .vis attribute). Backward-compatible for all existing call sites.
- New Vis methods delegate to the module-level functions — zero
  logic duplication, no back-reference from Vis to Material.
- Vis.to_gltf(name=...) / .export_mtlx(name=...) let callers on a
  standalone Vis set the name explicitly; the module-level form on
  a Material auto-populates from material.name as before.

Tests:
- TestAdapterPolymorphism pins (module fn vs Material) == (Vis form).
- TestVisAdapterMethods pins (m.vis.method == module_fn(m)).
- Drop-in claim also holds for the e2e path (test_e2e_vis.py's
  existing to_threejs tests unchanged and still green).

Related: build123d#1270 (downstream consumer motivating the
discoverability push), mat-vis#93 (architecturally-cleaner VisAsset
payload object proposal — this issue's methods become one-line
forwards to VisAsset.to_* once that lands).

Also folds in two test-claim-backfills from the build123d#1270
comment draft:
- tests/test_e2e_vis.py::test_mtlx_xml_returns_materialx_string
- tests/test_integration.py::TestGltfMaterialPassthrough (pins the
  real behavior: apply_to preserves base-color only; direct
  shape.material doesn't reach export_gltf at all today — the gap
  that build123d#1270 closes).
Gaps the previous commit left open:

- Detached-Vis path (no owning Material) was never exercised — only
  Material-wrapped Vis. Every adapter now has a detached-Vis test.
- Duck-typing invariant ``hasattr(vis, "vis") is False`` was
  implicit. Pinned so a future refactor can't silently break
  ``_resolve_vis_and_name``.
- ``to_gltf(obj, name=...)`` keyword-only contract was untested.
  Added a positional-call TypeError test.
- Method surface (``hasattr(v, "to_gltf")`` etc.) wasn't asserted
  separately — now a dedicated test.
- ``export_mtlx(vis, out)`` without ``name=`` had no pin — added.
- Trimmed a redundant assertion (``"Stem" in stem or stem == "Stem"``).
@gerchowl gerchowl merged commit e3afd96 into main Apr 19, 2026
28 of 30 checks passed
@gerchowl gerchowl deleted the feature/78-vis-adapter-methods branch April 19, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vis.to_gltf() / .to_threejs() / .export_mtlx() method sugar

1 participant